
package org.linlinjava.litemall.core.qcode;

import cn.binarywang.wx.miniapp.api.WxMaService;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.storage.StorageService;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.db.domain.LitemallGroupon;
import org.linlinjava.litemall.db.domain.LitemallStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

@Service
public class QCodeService {

	private final Log logger = LogFactory.getLog(QCodeService.class);

	@Autowired
	private WxMaService wxMaService;

	@Autowired
	private StorageService storageService;

	public String createGrouponShareImage(String goodName, String goodPicUrl, LitemallGroupon groupon) {
		try {
			// 创建该商品的二维码
			File file = wxMaService.getQrcodeService().createWxaCodeUnlimit("groupon," + groupon.getId(),
				"pages/index/index");
			FileInputStream inputStream = new FileInputStream(file);
			// 将商品图片，商品名字,商城名字画到模版图中
			byte[] imageData = drawPicture(inputStream, goodPicUrl, goodName);
			ByteArrayInputStream inputStream2 = new ByteArrayInputStream(imageData);
			// 存储分享图
			LitemallStorage storageInfo = storageService.store(inputStream2, imageData.length, "image/jpeg",
				getKeyName(groupon.getId().toString()));
			return storageInfo.getUrl();
		} catch (WxErrorException e) {
			logger.error(e.getMessage(), e);
		} catch (FileNotFoundException e) {
			logger.error(e.getMessage(), e);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}
		return "";
	}

	/**
	 * 创建商品分享图
	 *
	 * @param goodId
	 * @param goodPicUrl
	 * @param goodName
	 */
	public String createGoodShareImage(String goodId, String goodPicUrl, String goodName) {
		if (!SystemConfig.isAutoCreateShareImage()) {
			return "";
		}
		try {
			// 创建该商品的二维码
			File file = wxMaService.getQrcodeService().createWxaCodeUnlimit("goods," + goodId, "pages/index/index");
			FileInputStream inputStream = new FileInputStream(file);
			// 将商品图片，商品名字,商城名字画到模版图中
			byte[] imageData = drawPicture(inputStream, goodPicUrl, goodName);
			ByteArrayInputStream inputStream2 = new ByteArrayInputStream(imageData);
			// 存储分享图
			LitemallStorage litemallStorage = storageService.store(inputStream2, imageData.length, "image/jpeg",
				getKeyName(goodId));
			return litemallStorage.getUrl();
		} catch (WxErrorException e) {
			logger.error(e.getMessage(), e);
		} catch (FileNotFoundException e) {
			logger.error(e.getMessage(), e);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}
		return "";
	}

	private String getKeyName(String goodId) {
		return "GOOD_QCODE_" + goodId + ".jpg";
	}

	/**
	 * 将商品图片，商品名字画到模版图中
	 *
	 * @param qrCodeImg  二维码图片
	 * @param goodPicUrl 商品图片地址
	 * @param goodName   商品名称
	 * @return
	 * @throws IOException
	 */
	private byte[] drawPicture(InputStream qrCodeImg, String goodPicUrl, String goodName) throws IOException {
		// 底图
		ClassPathResource redResource = new ClassPathResource("back.png");
		BufferedImage red = ImageIO.read(redResource.getInputStream());
		// 商品图片
		URL goodPic = new URL(goodPicUrl);
		BufferedImage goodImage = ImageIO.read(goodPic);
		// 小程序二维码
		BufferedImage qrCodeImage = ImageIO.read(qrCodeImg);
		// --- 画图 ---
		// 底层空白 bufferedImage
		BufferedImage baseImage = new BufferedImage(red.getWidth(), red.getHeight(), BufferedImage.TYPE_4BYTE_ABGR_PRE);
		// 画上图片
		drawImgInImg(baseImage, red, 0, 0, red.getWidth(), red.getHeight());
		// 画上商品图片
		drawImgInImg(baseImage, goodImage, 71, 69, 660, 660);
		// 画上小程序二维码
		drawImgInImg(baseImage, qrCodeImage, 448, 767, 300, 300);
		// 写上商品名称
		drawTextInImg(baseImage, goodName, 65, 867);
		// 写上商城名称
		// drawTextInImgCenter(baseImage, shopName, 98);
		// 转jpg
		BufferedImage result = new BufferedImage(baseImage.getWidth(), baseImage.getHeight(),
			BufferedImage.TYPE_3BYTE_BGR);
		result.getGraphics().drawImage(baseImage, 0, 0, null);
		ByteArrayOutputStream bs = new ByteArrayOutputStream();
		ImageIO.write(result, "jpg", bs);
		// 最终byte数组
		return bs.toByteArray();
	}

	@SuppressWarnings("unused")
	private void drawTextInImgCenter(BufferedImage baseImage, String textToWrite, int y) {
		Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
		g2D.setColor(new Color(167, 136, 69));
		String fontName = "Microsoft YaHei";
		Font f = new Font(fontName, Font.PLAIN, 28);
		g2D.setFont(f);
		g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		// 计算文字长度，计算居中的x点坐标
		FontMetrics fm = g2D.getFontMetrics(f);
		int textWidth = fm.stringWidth(textToWrite);
		int widthX = (baseImage.getWidth() - textWidth) / 2;
		// 表示这段文字在图片上的位置(x,y) .第一个是你设置的内容。
		g2D.drawString(textToWrite, widthX, y);
		// 释放对象
		g2D.dispose();
	}

	private void drawTextInImg(BufferedImage baseImage, String textToWrite, int x, int y) {
		Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
		g2D.setColor(new Color(167, 136, 69));
		// 注意，这里的字体必须安装在服务器上
		g2D.setFont(new Font("Microsoft YaHei", Font.PLAIN, 28));
		g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2D.drawString(textToWrite, x, y);
		g2D.dispose();
	}

	private void drawImgInImg(BufferedImage baseImage, BufferedImage imageToWrite,
		int x, int y, int width, int heigth) {
		Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
		g2D.drawImage(imageToWrite, x, y, width, heigth, null);
		g2D.dispose();
	}
}